package com.health.ts.utils;

import java.util.Collection;
import java.util.Map;

import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import com.health.ts.exception.BusinessException;

/**
 * 业务断言工具类
 * 
 */
public class AssertUtil {

	/**
	 * 断言 true
	 * 
	 * @param expression 表达式
	 * @param code       错误码
	 * @param message    消息
	 */
	public static void isTrue(boolean expression, String message) {
		if (!expression) {
			throw new BusinessException(message);
		}
	}

	/**
	 * 断言 对象空
	 * 
	 * @param object  对象
	 * @param code    错误码
	 * @param message 消息
	 */
	public static void isNull(Object object, String message) {
		if (object != null) {
			throw new BusinessException(message);
		}
	}

	/**
	 * 断言 对象非空
	 * 
	 * @param object  对象
	 * @param code    错误码
	 * @param message 消息
	 */
	public static void notNull(Object object, String message) {
		if (object == null) {
			throw new BusinessException(message);
		}
	}

	/**
	 * 断言 字符串不为空
	 * 
	 * @param text    文本
	 * @param code    错误码
	 * @param message 消息
	 */
	public static void hasLength(String text, String message) {
		if (!StringUtils.hasLength(text)) {
			throw new BusinessException(message);
		}
	}

	/**
	 * 断言数组不为空
	 * 
	 * @param array   数组
	 * @param code    错误码
	 * @param message 消息
	 */
	public static void notEmpty(Object[] array, String message) {
		if (ObjectUtils.isEmpty(array)) {
			throw new BusinessException(message);
		}
	}

	/**
	 * 断言集合不为空
	 * 
	 * @param collection 集合
	 * @param code       错误码
	 * @param message    消息
	 */
	public static void notEmpty(Collection<?> collection, String message) {
		if (CollectionUtils.isEmpty(collection)) {
			throw new BusinessException(message);
		}
	}

	/**
	 * 断言map不为空
	 * 
	 * @param map     map表
	 * @param code    错误码
	 * @param message 消息
	 */
	public static void notEmpty(Map<?, ?> map,String message) {
		if (CollectionUtils.isEmpty(map)) {
			throw new BusinessException(message);
		}
	}
	
	/**
	 * 断言数组为空
	 * 
	 * @param array   数组
	 * @param code    错误码
	 * @param message 消息
	 */
	public static void empty(Object[] array, String message) {
		if (!ObjectUtils.isEmpty(array)) {
			throw new BusinessException(message);
		}
	}

	/**
	 * 断言集合为空
	 * 
	 * @param collection 集合
	 * @param code       错误码
	 * @param message    消息
	 */
	public static void empty(Collection<?> collection, String message) {
		if (!CollectionUtils.isEmpty(collection)) {
			throw new BusinessException(message);
		}
	}

	/**
	 * 断言map为空
	 * 
	 * @param map     map表
	 * @param code    错误码
	 * @param message 消息
	 */
	public static void empty(Map<?, ?> map, String message) {
		if (!CollectionUtils.isEmpty(map)) {
			throw new BusinessException(message);
		}
	}

	/**
	 * 断言对象属于某类
	 * 
	 * @param type    类
	 * @param obj     对象
	 * @param code    错误码
	 * @param message 消息
	 */
	public static void isInstanceOf(Class<?> type, Object obj,String message) {
		notNull(type, "Type to check against must not be null");
		if (!type.isInstance(obj)) {
			instanceCheckFailed(type, obj, message);
		}
	}

	/**
	 * 类型校验
	 * 
	 * @param type 类
	 * @param obj  对象
	 * @param code 错误码
	 * @param msg  消息
	 */
	private static void instanceCheckFailed(Class<?> type, Object obj, String msg) {
		String className = (obj != null ? obj.getClass().getName() : "null");
		String result = "";
		boolean defaultMessage = true;
		if (StringUtils.hasLength(msg)) {
			if (endsWithSeparator(msg)) {
				result = msg + " ";
			} else {
				result = messageWithTypeName(msg, className);
				defaultMessage = false;
			}
		}
		if (defaultMessage) {
			result = result + ("Object of class [" + className + "] must be an instance of " + type);
		}
		throw new BusinessException(msg);
	}

	/**
	 * endsWithSeparator
	 * 
	 * @param msg msg
	 * @return boolean
	 */
	private static boolean endsWithSeparator(String msg) {
		return (msg.endsWith(":") || msg.endsWith(";") || msg.endsWith(",") || msg.endsWith("."));
	}

	/**
	 * messageWithTypeName
	 * 
	 * @param msg      msg
	 * @param typeName typeName
	 * @return String
	 */
	private static String messageWithTypeName(String msg, Object typeName) {
		return msg + (msg.endsWith(" ") ? "" : ": ") + typeName;
	}
}
